package com.huayun.util.utils;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.text.TextUtils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import com.huayun.util.UtilInit;
import com.huayun.util.inter_face.Action;

/**
 * Description: 文件存储的工具类
 * <p>
 * Created on 2018/4/16 11:28:46
 * author:Ahuangshang
 */

public class FileUtil {
    /**
     * 保存文件到指定位置
     *
     * @param data     文件内容
     * @param FileName 文件全路径
     */
    public static void save(String data, String FileName) {
        FileOutputStream out = null;
        BufferedWriter writer = null;
        try {
            //设置文件名称，以及存储方式
            out = new FileOutputStream(new File(FileName));
            //创建一个OutputStreamWriter对象，传入BufferedWriter的构造器中
            writer = new BufferedWriter(new OutputStreamWriter(out, "utf-8"));
            //向文件中写入数据
            writer.write(data);
            writer.flush();
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 保存文件到指定位置
     *
     * @param data     文件内容
     * @param FileName 文件全路径
     */
    public static void saveAppend(String data, String FileName) {
        FileOutputStream out = null;
        BufferedWriter writer = null;
        try {
            //设置文件名称，以及存储方式
            out = new FileOutputStream(new File(FileName), true);
            //创建一个OutputStreamWriter对象，传入BufferedWriter的构造器中
            writer = new BufferedWriter(new OutputStreamWriter(out, "utf-8"));
            //向文件中写入数据
            writer.write(data);
            writer.flush();
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 我们将请求到的JSON数据存储在文件中，我们每次从文件中读取存储的数据，
     * 为了防止IO读写异常，我们也以SharedPreferences存储一份，当我们从文件中没有读到想要的数据时，就从SharedPreferences中读取。
     */
    public static void save(Context context, String data, String FileName) {
        //data = "Data to save";
        FileOutputStream out = null;
        BufferedWriter writer = null;
        try {
            //设置文件名称，以及存储方式
            out = context.openFileOutput(FileName, Context.MODE_PRIVATE);
            //创建一个OutputStreamWriter对象，传入BufferedWriter的构造器中
            writer = new BufferedWriter(new OutputStreamWriter(out));
            //向文件中写入数据
            writer.write(data);

        } catch (IOException e) {
            e.printStackTrace();
            LogUtil.e(e.getMessage());
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
                LogUtil.e(e.getMessage());
            }
        }
        SharedPreferenceUtil.put(FileName, data);
    }


    public static String load(Context context, String FileName) {
        FileInputStream in = null;
        BufferedReader reader = null;
        StringBuilder content = new StringBuilder();
        try {
            //设置将要打开的存储文件名称
            in = context.openFileInput(FileName);
            //FileInputStream -> InputStreamReader ->BufferedReader
            reader = new BufferedReader(new InputStreamReader(in));
            String line;
            //读取每一行数据，并追加到StringBuilder对象中，直到结束
            while ((line = reader.readLine()) != null) {
                content.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
            LogUtil.e(e.getMessage());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    LogUtil.e(e.getMessage());
                }
            }
        }
        if (TextUtils.isEmpty(content.toString())) {
            content.append(SharedPreferenceUtil.get(FileName, ""));
        }
        return content.toString();
    }

    public static String read(File file) {
        StringBuilder sb = new StringBuilder();
        try {
            InputStream inputstream = new FileInputStream(file);
            if (inputstream != null) {
                InputStreamReader inputreader =
                        new InputStreamReader(inputstream, "UTF-8");
                BufferedReader buffreader =
                        new BufferedReader(inputreader);
                String line = "";
                //分行读取
                while ((line = buffreader.readLine()) != null) {
                    sb.append(line);
                }
                inputstream.close();
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        return sb.toString();
    }

    /**
     * 获取应用专属缓存目录
     * android 4.4及以上系统不需要申请SD卡读写权限
     * 因此也不用考虑6.0系统动态申请SD卡读写权限问题，切随应用被卸载后自动清空 不会污染用户存储空间
     *
     * @param context 上下文
     * @param type    文件夹类型 可以为空，为空则返回API得到的一级目录
     * @return 缓存文件夹 如果没有SD卡或SD卡有问题则返回内存缓存目录，否则优先返回SD卡缓存目录
     */
    public static File getCacheDirectory(Context context, String type) {
        File appCacheDir = getExternalCacheDirectory(context, type);
        if (appCacheDir == null) {
            appCacheDir = getInternalCacheDirectory(context, type);
        }
        if (appCacheDir == null) {
            LogUtil.e("getCacheDirectory fail ,the reason is mobile phone unknown exception !");
        } else {
            if (!appCacheDir.exists() && !appCacheDir.mkdirs()) {
                LogUtil.e("getCacheDirectory fail ,the reason is make directory fail !");
            }
        }
        return appCacheDir;
    }

    /**
     * 获取SD卡缓存目录
     *
     * @param context 上下文
     * @param type    文件夹类型 如果为空则返回 /storage/emulated/0/Android/data/app_package_name/cache
     *                否则返回对应类型的文件夹如Environment.DIRECTORY_PICTURES 对应的文件夹为 .../data/app_package_name/files/Pictures
     *                {@link Environment#DIRECTORY_MUSIC},
     *                {@link Environment#DIRECTORY_PODCASTS},
     *                {@link Environment#DIRECTORY_RINGTONES},
     *                {@link Environment#DIRECTORY_ALARMS},
     *                {@link Environment#DIRECTORY_NOTIFICATIONS},
     *                {@link Environment#DIRECTORY_PICTURES}, or
     *                {@link Environment#DIRECTORY_MOVIES}.or 自定义文件夹名称
     * @return 缓存目录文件夹 或 null（无SD卡或SD卡挂载失败）
     */
    public static File getExternalCacheDirectory(Context context, String type) {
        File appCacheDir = null;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            if (TextUtils.isEmpty(type)) {
                appCacheDir = context.getExternalCacheDir();
            } else {
                appCacheDir = context.getExternalFilesDir(type);
            }

            if (appCacheDir == null) {// 有些手机需要通过自定义目录
                appCacheDir = new File(Environment.getExternalStorageDirectory(), "Android/data/" + context.getPackageName() + "/cache/" + type);
            }

            if (appCacheDir == null) {
                LogUtil.e("getExternalDirectory fail ,the reason is sdCard unknown exception !");
            } else {
                if (!appCacheDir.exists() && !appCacheDir.mkdirs()) {
                    LogUtil.e("getExternalDirectory fail ,the reason is make directory fail !");
                }
            }
        } else {
            LogUtil.e("getExternalDirectory fail ,the reason is sdCard nonexistence or sdCard mount fail !");
        }
        return appCacheDir;
    }

    /**
     * 获取内存缓存目录
     *
     * @param type 子目录，可以为空，为空直接返回一级目录
     * @return 缓存目录文件夹 或 null（创建目录文件失败）
     * 注：该方法获取的目录是能供当前应用自己使用，外部应用没有读写权限，如 系统相机应用
     */
    public static File getInternalCacheDirectory(Context context, String type) {
        File appCacheDir = null;
        if (TextUtils.isEmpty(type)) {
            appCacheDir = context.getCacheDir();// /data/data/app_package_name/cache
        } else {
            appCacheDir = new File(context.getFilesDir(), type);// /data/data/app_package_name/files/type
        }

        if (!appCacheDir.exists() && !appCacheDir.mkdirs()) {
            LogUtil.e("getInternalDirectory fail ,the reason is make directory fail !");
        }
        return appCacheDir;
    }

    public static byte[] getBytesFromInputStream(InputStream inputStream) throws IOException {
        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024]; // 用数据装
        int len = -1;
        while ((len = inputStream.read(buffer)) != -1) {
            outstream.write(buffer, 0, len);
        }
        outstream.close();
        // 关闭流一定要记得。
        return outstream.toByteArray();
    }

    /**
     * 删除单个文件
     *
     * @param file 被删除文件
     * @return 文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(File file) {
        if (file.isFile() && file.exists()) {
            return file.delete();
        }
        return false;
    }

    public static void deleteFileSrc(File file) {
        if (file.isFile() && file.exists()) {
            file.delete();
            return;
        }
        if (file.isDirectory()) {
            File[] childFile = file.listFiles();
            if (childFile == null || childFile.length == 0) {
                file.delete();
                return;
            }
            for (File f : childFile) {
                deleteFile(f);
            }
            file.delete();
        }
    }

    public static void copyAssetsFileToSDCard(String assetsPath, String sdcardPath, Action<String> listener) {
        copyAssetsFileToSDCardThread(assetsPath, sdcardPath, listener);
    }

    public static void copyAssetsFileToSDCardThread(final String assetsPath, final String sdcardPath, final Action<String> listener) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                InputStream in = null;
                OutputStream os = null;
                try {
                    // 获取.db在assets中的输入流
                    in = UtilInit.getApplicationContext().getAssets().open(assetsPath);
                    // 获取.db需要在SDCARD中存放的输出流
                    os = new FileOutputStream(sdcardPath);
                    // 定义缓冲器
                    byte[] buffer = new byte[1024];
                    // 当前读取数据的长度
                    int len = 0;
                    // 读取输入流到数组中
                    while ((len = in.read(buffer)) != -1) {
                        os.write(buffer, 0, len);
                    }
                    // 提交缓冲区文件
                    os.flush();
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                } finally {
                    if (listener != null) {
                        listener.call("finish");
                    }
                    // 关闭流
                    try {
                        if (os != null) {
                            os.close();
                        }
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    try {
                        if (in != null) {
                            in.close();
                        }
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    /**
     * 从assets 文件夹中读取图片
     */
    public static Drawable loadImageFromAsserts(String fileName) {
        InputStream is = null;
        Drawable drawable = null;
        try {
            is = UtilInit.getApplicationContext().getResources().getAssets().open(fileName);
            drawable = Drawable.createFromStream(is, null);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return drawable;
    }
}
